package com.ag.improvedjava.iterable;

import java.util.Iterator;
import java.util.NoSuchElementException;

import com.ag.improvedjava.utils.Predicate;

final class SkipWhileIterable<T> implements Iterable<T> {

	private final Iterable<T> iterable;
	private final Predicate<T> predicate;
	
	SkipWhileIterable(Iterable<T> iterable, Predicate<T> predicate) {
		this.iterable = iterable;
		this.predicate = predicate;
	}

	@Override
	public Iterator<T> iterator() {
		return new SkipWhileIterator<>(iterable.iterator(), predicate);
	}
}

class SkipWhileIterator<T> extends UnmodifiableIterator<T> {
	
	private final Iterator<T> iterator;
	private final Predicate<T> predicate;
	private T next;
	private boolean canIterate = true;
	private boolean hasNext = false;
	private boolean checkPredicate = true;
	
	SkipWhileIterator(Iterator<T> iterator, Predicate<T> predicate) {
		this.iterator = iterator;
		this.predicate = predicate;
	}

	@Override
	public boolean hasNext() {
		if (canIterate) {
			canIterate = false;
			if (!iterator.hasNext()) {
				hasNext = false;
			} else if (!checkPredicate) {
				next = iterator.next();
			} else {
				while (checkPredicate && iterator.hasNext()) {
					next = iterator.next();
					if (!predicate.evaluate(next)) {
						checkPredicate = false;
						hasNext = true;
					}
				}
			}
		}
		return hasNext;
	}		

	@Override
	public T next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		canIterate = true;
		return next;
	}

}
